package com.aisb.manage;

import com.aisb.common.CommonService;
import com.aisb.core.InitParam;
import com.aisb.core.SessionBean;
import com.aisb.core.shiro.ShiroDao;
import com.aisb.core.util.DateUtil;
import com.github.pagehelper.Page;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @Description：
 * @Author wucm
 * @Date 2017/12/28
 */
@Service
public class UserService {
    private static Logger logger = LoggerFactory.getLogger(UserService.class);


    @Autowired
    UserDao userDao;

    @Autowired
    CommonService commonService;

    @Autowired
    AuthDao authDao;

    @Autowired
    ShiroDao shiroDao;

    public Object userOne(String userId) {
        Map user = (Map) userDao.queryOne(userId);
        userInfoDeal(user);
        userInfoFuncDeal(user);
        return user;
    }

    public Object userOne(Map param) {
        return userDao.queryOne(param);
    }

    public List userList(Map param) {
        List<Map> userList = userDao.queryList(param);
        userInfoDeal(userList);

        return userList;
    }

    public Page userList(Map param, Integer pageNum, Integer pageSize) {
        if (null == pageNum) {
            pageNum = 1;
        }
        if (null == pageSize) {
            pageSize = 999999;
        }

        Page users = userDao.searchPage(param, pageNum, pageSize);
        List<Map> result = users.getResult();
        userInfoDeal(result);

        return users;
    }

    /**
     * 用户额外信息处理
     *
     * @param userList
     */
    private void userInfoDeal(List<Map> userList) {
        // 地域信息
        Map<String, Map> areaMap = commonService.areaSimpleMap();
        // 角色信息
        Map<String, List> rMap = commonService.rolesForAllUser();

        for (Map m : userList) {
            // 地域信息
            String areaId = (String) m.get("areaId");
            Map areaInfo = areaMap.get(areaId);
            if (null != areaInfo) {
                m.put("areaName", areaInfo.get("name"));
            }

            // 角色信息
            String userId = (String) m.get("userId");
            List<Map> rList = rMap.get(userId);
            Set<String> roleIdSet = new HashSet<>();
            Set<String> roleNameSet = new HashSet<>();
            if (null != rList) {
                for (Map r : rList) {
                    roleIdSet.add((String) r.get("roleId"));
                    roleNameSet.add((String) r.get("roleName"));
                }
            }
            m.put("roleIds", StringUtils.join(roleIdSet.toArray(), "/"));
            m.put("roleNames", StringUtils.join(roleNameSet.toArray(), " / "));
        }
    }

    /**
     * 用户额外信息处理
     *
     * @param m
     */
    private void userInfoDeal(Map m) {
        // 地域信息
        Map<String, Map> areaMap = commonService.areaSimpleMap();
        // 角色信息
        Map<String, List> rMap = commonService.rolesForAllUser();

        // 地域信息
        String areaId = (String) m.get("areaId");
        Map areaInfo = areaMap.get(areaId);
        if (null != areaInfo) {
            m.put("areaName", areaInfo.get("name"));
        }

        // 角色信息
        String userId = (String) m.get("userId");
        List<Map> rList = rMap.get(userId);
        Set<String> roleNameSet = new HashSet<>();
        if (null != rList) {
            for (Map r : rList) {
                roleNameSet.add((String) r.get("roleName"));
            }
        }
        m.put("roleNames", StringUtils.join(roleNameSet.toArray(), " / "));

    }

    private void userInfoFuncDeal(Map user) {
        String userId = (String) user.get("userId");

        LinkedHashSet<String> userFuncs = new LinkedHashSet<>();
        LinkedHashSet<String> userOpers = new LinkedHashSet<>();

        // 功能权限和操作权限
        List<Map> funcs = shiroDao.funcAll();
        List<Map> funcByUserList = shiroDao.funcByUser(userId);
        List<Map> funcByRoleUserList = shiroDao.funcByRoleUser(userId);
        List<Map> operByUserList = shiroDao.operByUser(userId);
        List<Map> operByRoleUserList = shiroDao.operByRoleUser(userId);

        Set viewSet = new HashSet();
        Set addSet = new HashSet();
        Set modifySet = new HashSet();
        Set deleteSet = new HashSet();
        Set uploadSet = new HashSet();
        Set downloadSet = new HashSet();

        // 用户直接拥有的功能权限和操作权限
        for (Map m : funcByUserList) {
            String funcId = (String) m.get("funcId");
            String pAdd = (String) m.get("pAdd");
            String pModify = (String) m.get("pModify");
            String pDelete = (String) m.get("pDelete");
            String pUpload = (String) m.get("pUpload");
            String pDownload = (String) m.get("pDownload");

            viewSet.add(funcId);
            if ("true".equals(pAdd)) {
                addSet.add(funcId);
            }
            if ("true".equals(pModify)) {
                modifySet.add(funcId);
            }
            if ("true".equals(pDelete)) {
                deleteSet.add(funcId);
            }
            if ("true".equals(pUpload)) {
                uploadSet.add(funcId);
            }
            if ("true".equals(pDownload)) {
                downloadSet.add(funcId);
            }
        }

        // 用户通过角色间接拥有的功能权限和操作权限
        for (Map m : funcByRoleUserList) {
            String funcId = (String) m.get("funcId");
            String pAdd = (String) m.get("pAdd");
            String pModify = (String) m.get("pModify");
            String pDelete = (String) m.get("pDelete");
            String pUpload = (String) m.get("pUpload");
            String pDownload = (String) m.get("pDownload");

            viewSet.add(funcId);
            if ("true".equals(pAdd)) {
                addSet.add(funcId);
            }
            if ("true".equals(pModify)) {
                modifySet.add(funcId);
            }
            if ("true".equals(pDelete)) {
                deleteSet.add(funcId);
            }
            if ("true".equals(pUpload)) {
                uploadSet.add(funcId);
            }
            if ("true".equals(pDownload)) {
                downloadSet.add(funcId);
            }
        }

        boolean addFlag = false;
        boolean modifyFlag = false;
        boolean deleteFlag = false;
        boolean uploadFlag = false;
        boolean downloadFlag = false;

        // 用户直接拥有的操作权限
        for (Map m : operByUserList) {
            String pAdd = (String) m.get("pAdd");
            String pModify = (String) m.get("pModify");
            String pDelete = (String) m.get("pDelete");
            String pUpload = (String) m.get("pUpload");
            String pDownload = (String) m.get("pDownload");
            if ("true".equals(pAdd)) {
                addFlag = true;
            }
            if ("true".equals(pModify)) {
                modifyFlag = true;
            }
            if ("true".equals(pDelete)) {
                deleteFlag = true;
            }
            if ("true".equals(pUpload)) {
                uploadFlag = true;
            }
            if ("true".equals(pDownload)) {
                downloadFlag = true;
            }
        }

        // 用户通过角色间接拥有的操作权限
        for (Map m : funcByRoleUserList) {
            String pAdd = (String) m.get("pAdd");
            String pModify = (String) m.get("pModify");
            String pDelete = (String) m.get("pDelete");
            String pUpload = (String) m.get("pUpload");
            String pDownload = (String) m.get("pDownload");
            if ("true".equals(pAdd)) {
                addFlag = true;
            }
            if ("true".equals(pModify)) {
                modifyFlag = true;
            }
            if ("true".equals(pDelete)) {
                deleteFlag = true;
            }
            if ("true".equals(pUpload)) {
                uploadFlag = true;
            }
            if ("true".equals(pDownload)) {
                downloadFlag = true;
            }
        }

        for (Map func : funcs) {
            String funcId = (String) func.get("funcId");
            String funcName = (String) func.get("funcName");
            String funcUrl = (String) func.get("funcUrl");
            if (StringUtils.isBlank(funcUrl)) {
                continue;
            }
            if (funcUrl.endsWith("/")) {
                funcUrl = funcUrl.substring(0, funcUrl.length());
            }

            if (!viewSet.contains(funcId)) {
                continue;
            }
            userFuncs.add(funcName);
            if (funcUrl.endsWith("/index")) {// 获取功能授权关键KEY
                funcUrl = funcUrl.replace("/index", "");
            }
            if (addSet.contains(funcId) || addFlag) {
                userOpers.add(funcName + "【新增】");
            }
            if (modifySet.contains(funcId) || modifyFlag) {
                userOpers.add(funcName + "【修改】");
            }

            if (deleteSet.contains(funcId) || deleteFlag) {
                userOpers.add(funcName + "【删除】");
            }

            if (uploadSet.contains(funcId) || uploadFlag) {
                userOpers.add(funcName + "【导入】");
            }

            if (downloadSet.contains(funcId) || downloadFlag) {
                userOpers.add(funcName + "【导出】");
            }
        }
        user.put("userFuncs", StringUtils.join(userFuncs.toArray(), " / "));
        user.put("userOpers", StringUtils.join(userOpers.toArray(), " / "));
    }

    @Transactional
    public int userAdd(Map param) {
        SessionBean sessionBean = (SessionBean) SecurityUtils.getSubject().getPrincipal();

        try {
            userDao.insert(param);

            param.put("adminId", sessionBean.getUserId());
            param.put("adminName", sessionBean.getUserName());
            param.put("adminTime", DateUtil.getInstance().getToday(InitParam.FORMAT_TIME));

            if (param.containsKey("roleIds")) {
                String[] roles = ((String) param.get("roleIds")).split(",");
                if (null != roles && roles.length > 0) {
                    for (String roleId : roles) {
                        param.put("roleId", roleId);
                        authDao.authAddRoleUser(param);
                    }
                }
            }
        } catch (Exception e) {
            logger.error("{}", e);
            return 0;
        }

        return 1;
    }

    @Transactional
    public int userModify(Map modifyInfo) {
        try {
            userDao.update(modifyInfo);
        } catch (Exception e) {
            logger.error("{}", e);
            return 0;
        }

        return 1;
    }

    @Transactional
    public int userModify(Set<String> userIds, Map modifyInfo) {
        try {
            for (String userId : userIds) {
                if (StringUtils.isBlank(userId)) {
                    continue;
                }
                modifyInfo.put("userId", userId);
                userDao.update(modifyInfo);
            }
        } catch (Exception e) {
            logger.error("{}", e);
            return 0;
        }

        return 1;
    }

    /**
     * @param param
     * @param dealRole 是否处理和角色的关联关系
     * @return
     */
    @Transactional
    public int userModify(Map param, boolean dealRole) {
        try {
            String userIds = (String) param.get("userIds");
            String userId = (String) param.get("userId");
            String roleIds = (String) param.get("roleIds");
            if (StringUtils.isNotBlank(userIds)) {
                userId = userId + "," + userIds;
            }
            if (StringUtils.isBlank(roleIds)) {
                roleIds = "";
            }
            Set<String> userIdSet = new HashSet(Arrays.asList(userId.split(",")));
            Set<String> roleIdSet = new HashSet(Arrays.asList(roleIds.split(",")));
            if (null != userIdSet) {
                for (String uId : userIdSet) {
                    if (StringUtils.isBlank(uId)) {
                        continue;
                    }
                    param.put("userId", uId);
                    userDao.update(param);

                    // 保存用户-角色
                    if (dealRole) {
                        authDao.authDeleteRoleUserByUserId(param);
                        if (null != roleIdSet && roleIdSet.size() > 0) {
                            for (String roleId : roleIdSet) {
                                if (StringUtils.isBlank(roleId)) {
                                    continue;
                                }
                                param.put("roleId", roleId);
                                authDao.authAddRoleUser(param);
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error("{}", e);
            return 0;
        }

        return 1;
    }

    @Transactional
    public int userDelete(Map param) {
        try {
            userDao.delete(param);
            userDao.deleteUserFunc(param);
            userDao.deleteUserOper(param);
            userDao.deleteUserRole(param);
        } catch (Exception e) {
            logger.error("{}", e);
            return 0;
        }

        return 1;
    }
}
